package com.asr.testclient.model;

import com.google.gson.Gson;
import com.google.gson.JsonObject;
import org.junit.jupiter.api.Test;

import static org.junit.jupiter.api.Assertions.*;

/**
 * 测试ClientMessage类
 */
class ClientMessageTest {
    
    private final Gson gson = new Gson();
    
    @Test
    void testConstructor_WithAllFields() {
        String type = "file_upload";
        String fileData = "SGVsbG8gV29ybGQ=";
        String filename = "test.wav";
        
        ClientMessage message = new ClientMessage(type, fileData, filename);
        
        assertEquals(type, message.getType());
        assertEquals(fileData, message.getFileData());
        assertEquals(filename, message.getFilename());
    }
    
    @Test
    void testConstructor_WithoutFilename() {
        String type = "file_upload";
        String fileData = "SGVsbG8gV29ybGQ=";
        
        ClientMessage message = new ClientMessage(type, fileData);
        
        assertEquals(type, message.getType());
        assertEquals(fileData, message.getFileData());
        assertNull(message.getFilename());
    }
    
    @Test
    void testToJson_WithAllFields() {
        String type = "file_upload";
        String fileData = "SGVsbG8gV29ybGQ=";
        String filename = "test.wav";
        
        ClientMessage message = new ClientMessage(type, fileData, filename);
        String json = message.toJson();
        
        // 验证JSON不为空
        assertNotNull(json);
        assertFalse(json.isEmpty());
        
        // 解析JSON并验证字段
        JsonObject jsonObject = gson.fromJson(json, JsonObject.class);
        assertEquals(type, jsonObject.get("type").getAsString());
        assertEquals(fileData, jsonObject.get("file_data").getAsString());
        assertEquals(filename, jsonObject.get("filename").getAsString());
    }
    
    @Test
    void testToJson_WithoutFilename() {
        String type = "file_upload";
        String fileData = "SGVsbG8gV29ybGQ=";
        
        ClientMessage message = new ClientMessage(type, fileData);
        String json = message.toJson();
        
        // 验证JSON不为空
        assertNotNull(json);
        assertFalse(json.isEmpty());
        
        // 解析JSON并验证字段
        JsonObject jsonObject = gson.fromJson(json, JsonObject.class);
        assertEquals(type, jsonObject.get("type").getAsString());
        assertEquals(fileData, jsonObject.get("file_data").getAsString());
        
        // filename应该为null
        if (jsonObject.has("filename")) {
            assertTrue(jsonObject.get("filename").isJsonNull());
        }
    }
    
    @Test
    void testToJson_SerializationCorrectness() {
        // 测试JSON序列化的正确性
        ClientMessage message = new ClientMessage("file_upload", "dGVzdCBkYXRh", "audio.wav");
        String json = message.toJson();
        
        // 反序列化并验证
        JsonObject jsonObject = gson.fromJson(json, JsonObject.class);
        
        // 验证所有必填字段都存在
        assertTrue(jsonObject.has("type"));
        assertTrue(jsonObject.has("file_data"));
        assertTrue(jsonObject.has("filename"));
        
        // 验证字段值正确
        assertEquals("file_upload", jsonObject.get("type").getAsString());
        assertEquals("dGVzdCBkYXRh", jsonObject.get("file_data").getAsString());
        assertEquals("audio.wav", jsonObject.get("filename").getAsString());
    }
    
    @Test
    void testToJson_WithEmptyStrings() {
        ClientMessage message = new ClientMessage("", "", "");
        String json = message.toJson();
        
        assertNotNull(json);
        
        JsonObject jsonObject = gson.fromJson(json, JsonObject.class);
        assertEquals("", jsonObject.get("type").getAsString());
        assertEquals("", jsonObject.get("file_data").getAsString());
        assertEquals("", jsonObject.get("filename").getAsString());
    }
    
    @Test
    void testToJson_WithSpecialCharacters() {
        // 测试包含特殊字符的数据
        String fileData = "SGVsbG8gV29ybGQh/+==";
        String filename = "测试文件.wav";
        
        ClientMessage message = new ClientMessage("file_upload", fileData, filename);
        String json = message.toJson();
        
        assertNotNull(json);
        
        // 验证可以正确解析回来
        JsonObject jsonObject = gson.fromJson(json, JsonObject.class);
        assertEquals(fileData, jsonObject.get("file_data").getAsString());
        assertEquals(filename, jsonObject.get("filename").getAsString());
    }
    
    @Test
    void testGetters() {
        String type = "file_upload";
        String fileData = "base64data";
        String filename = "test.wav";
        
        ClientMessage message = new ClientMessage(type, fileData, filename);
        
        // 验证所有getter方法
        assertEquals(type, message.getType());
        assertEquals(fileData, message.getFileData());
        assertEquals(filename, message.getFilename());
    }
}
